package edu.mse.camel.client.posterboard.ui.editor;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;

import com.cea.papyrus.core.editor.ModelManager;

import edu.mse.camel.client.posterboard.posterboard.Posterboard;
import edu.mse.camel.client.posterboard.ui.treeoutline.PosterboardTreeEditPart;
import edu.mse.camel.client.whiteboard.gef.whiteboard.WhiteboardDiagram;
import edu.mse.camel.client.whiteboard.gef.whiteboard.WhiteboardFactory;

public class PosterBoardModelManager {

	protected ComposedAdapterFactory adapterFactory;

	private ModelManager papyrusModelManager;

	private URI posterBoardURI;

	private Resource posterBoardResource;

	private ResourceSet posterBoardResourceSet;

	private Posterboard posterBoard;

	private PosterboardTreeEditPart pbTreeEditPart;

	private WhiteboardDiagram whiteBoard;

	private List<WhiteboardDiagram> additionalWBDiagrams;

	private List<Resource> additionalWBResources;

	private Resource whiteBoardResource;
	
	private IProject iProject;

	public PosterBoardModelManager(ComposedAdapterFactory adapterFactory) {
		this.adapterFactory = adapterFactory;
		papyrusModelManager = new ModelManager(adapterFactory);
		posterBoardResourceSet = papyrusModelManager.getResourceSet();
		additionalWBDiagrams = new ArrayList<WhiteboardDiagram>();
		additionalWBResources = new ArrayList<Resource>();
	}

	public ResourceSet getResourceSet() {
		// for now we use Papyrus' resource set
		return posterBoardResourceSet;
	}

	public void saveResources(IProgressMonitor monitor) {
		try {
			getPapyrusModelManager().getDiResourceSet().saveResources(monitor);
			posterBoardResource.save(null);
			whiteBoardResource.save(null);
			for (Resource newWB : additionalWBResources) {
				newWB.save(null);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void loadResources(IFile file) {

		loadPosterboard(file);

		// for now we will assume that the posterboard file and model file
		// are contained in the same project.
		if (posterBoard.getDiagramFile() != null) {
			// load model only if selected in the wizard
			IFile iFile = ResourcesPlugin.getWorkspace().getRoot().getFile(
					new Path(posterBoard.getDiagramFile()));
			papyrusModelManager.getDiResourceSet().loadResources(iFile);

		}
		this.iProject = file.getProject();
		if (posterBoard.getWhiteboardFile() != null) {
			// load whiteboard only if selected in the wizard
			loadWhiteBoard(file.getProject());
		}

	}

	private URI getNewWBURI(IProject project) {
		String fileNameWithExtn = posterBoard.getWhiteboardFile();
		int i = 2;
		String newFile;
		do {
			String fileNameWithoutExtn = fileNameWithExtn.substring(0,
					fileNameWithExtn.lastIndexOf('.'));
			newFile = fileNameWithoutExtn + "_" + i + ".whiteboard";
			++i;
		} while (project.getFile(newFile).exists());
		String newURI = "platform:/resource/" + project.getName() + "/"
				+ newFile;
		return URI.createURI(newURI);

	}

	private void loadWhiteBoard(IProject project) {
		URI wbURI = URI.createURI("platform:/resource/" + project.getName()
				+ "/" + posterBoard.getWhiteboardFile());
		whiteBoardResource = getResourceSet().getResource(wbURI, true);
		whiteBoard = (WhiteboardDiagram) whiteBoardResource.getContents()
				.get(0);
	}

	private void loadPosterboard(IFile file) {
		posterBoardURI = URI.createURI("platform:/resource"
				+ file.getFullPath().toString());
		posterBoardResource = getResourceSet()
				.getResource(posterBoardURI, true);
		posterBoard = (Posterboard) posterBoardResource.getContents().get(0);
	}

	public WhiteboardDiagram getWhiteboard() {
		return whiteBoard;
	}

	public Resource getWhiteboardResource() {
		return whiteBoardResource;
	}

	public Posterboard getPosterBoard() {
		return posterBoard;
	}

	public ModelManager getPapyrusModelManager() {
		return papyrusModelManager;
	}

	public void setPBTreeEditPart(
			PosterboardTreeEditPart posterboardTreeEditPart) {
		this.pbTreeEditPart = posterboardTreeEditPart;
	}

	public PosterboardTreeEditPart getPBTreeEditPart() {
		return pbTreeEditPart;
	}

	public void addWhiteboardResourceToResourceSet() {
		getResourceSet().getResources().add(whiteBoardResource);
	}

	public void removeWhiteboardResourceFromResourceSet() {
		getResourceSet().getResources().remove(whiteBoardResource);
	}

	public void addAdditionalWhiteboard(WhiteboardDiagram wbDiagram) {
		URI wbURI = getNewWBURI(this.iProject);
		createAdditionalWBResource(wbURI, wbDiagram);
		// add resource to the resource set
		Resource whiteBoardResource = getResourceSet().getResource(wbURI, true);
		additionalWBResources.add(whiteBoardResource);
		WhiteboardDiagram whiteBoard = (WhiteboardDiagram) whiteBoardResource.getContents()
				.get(0);
		additionalWBDiagrams.add(whiteBoard);
	}
	
	/**
	 * Will create a new Whiteboard
	 * 
	 * @return
	 */
	public WhiteboardDiagram getAdditionalWhiteboard() {
		URI wbURI = getNewWBURI(this.iProject);
		createAdditionalWBResource(wbURI);
		// add resource to the resource set
		Resource whiteBoardResource = getResourceSet().getResource(wbURI, true);
		additionalWBResources.add(whiteBoardResource);
		WhiteboardDiagram whiteBoard = (WhiteboardDiagram) whiteBoardResource.getContents()
				.get(0);
		additionalWBDiagrams.add(whiteBoard);
		return whiteBoard;
	}

	private void createAdditionalWBResource(URI wbURI) {
		WhiteboardDiagram wb = WhiteboardFactory.eINSTANCE.createWhiteboardDiagram();
		Resource res = new XMIResourceImpl(wbURI);
		res.getContents().add(wb);
		try {
			res.save(null);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	private void createAdditionalWBResource(URI wbURI, WhiteboardDiagram wb) {
		Resource res = new XMIResourceImpl(wbURI);
		res.getContents().add(wb);
		try {
			res.save(null);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
